/*
 * Receiver.cpp
 *
 *  Created on: 2010-01-22
 *      Author: Maciej Skrzypkowski
 */

#include "Receiver.h"
#include "SemLib.h"

Receiver::Receiver(TCPConnection * conn, SemLib* semLib, String serverName) {
	this->conn = conn;
	this->semLib = semLib;
	this->serverName = serverName;
	lock = new Lock(true, -1.0f);
	listMutex = new Lock(false, -1.0f);
}

Receiver::~Receiver() {

}


void Receiver::_run() {
	running = true;

	do {
		AnyMessage* rMsg = new AnyMessage;
		memset(rMsg, 0, sizeof(*rMsg));

		// receive message
		if(!conn->receive((uint8 *) rMsg, sizeof(*rMsg)))
		{
			Log::instance()->error("Polaczenie z serwerem " + conn->getIPAddress().hostname  + " zerwane przy odbieraniu wiadomości!");
			semLib->deleteServer(serverName);
			return;
		}

		if (rMsg->client.type < 0 || rMsg->client.type > 9) {
			std::ostringstream oss;
			oss << (int)rMsg->client.type;
			Log::instance()->warn("Nieznana wiadomość od serwera:" + oss.str() + " !");
		}

		switch (rMsg->client.type) {
		case MSG_PING:
			if (!semLib->sendPing(conn))
				return;
			break;
		default:
			std::ostringstream oss;
			oss << (int)rMsg->client.type;
			//Log::instance()->debug("Wiadomość:" + oss.str());
			listMutex->lock();
				msgList.push_back(rMsg);
			listMutex->unlock();
			lock->unlock();
			break;
		}
	} while (running);
}


AnyMessage* Receiver::getNewMsg() {
	AnyMessage* any = NULL;
	lock->lock();	// wait for message

	listMutex->lock();
		any = msgList.front();
		msgList.pop_front();
	listMutex->unlock();

	return any;
}


void Receiver::end() {
	running = false;
	this->stop();
}
